﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace GBT.Util
{
    public class ActiveDirectoryHelper
    {
        ///
        /// LDAP绑定路径，参考域地址LDAP://ptr.petreoshcna
        ///
        //private static string ADPath = ConfigurationManager.AppSettings["ptr"];
        private static readonly string ADPath = "LDAP://source-xm.com";

        /// <summary>
        /// 通过用户名密码验证是否能够登录
        /// </summary>
        /// <param name="Account"></param>
        /// <param name="Password"></param>
        /// <returns>返回true表示账号密码正确，登录验证通过</returns>
        public bool Validate(string Account, string Password)
        {
            DirectoryEntry Entry;

            //创建验证用的实例
#pragma warning disable CA1416 // 验证平台兼容性
            DirectoryEntry entry = new DirectoryEntry(ADPath, Account, Password);
            try
            {
                object obj = entry.NativeObject;
                DirectorySearcher search = new DirectorySearcher(entry)
                {
                    //搜索条件是SAMAccountName
                    Filter = "(SAMAccountName= " + Account + ") "
                };
                search.PropertiesToLoad.Add("cn");
                //获取搜索结果
                Entry = search.FindOne().GetDirectoryEntry();
#pragma warning restore CA1416 // 验证平台兼容性
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary> 
        /// 读取AD用户信息
        /// </summary> 
        /// <param name="userLoginInfo"></param>
        /// <returns></returns> 
        public UserInfo AdUserInfo(UserLoginInfo userLoginInfo)
        {
            UserInfo userInfo = new UserInfo();
            if (ADUserValidate(userLoginInfo.LoginName, userLoginInfo.Password))
            {
                DirectorySearcher src;
                //string ADPath = "LDAP:// " + domain;//   "ou=总公司,DC=abc,DC=com,DC=cn ";   + ",ou=总公司 " 
                //string ADPath = ADPath

                string domain = ADPath.Replace("LDAP://", "");

                SortedList<string, string> _sortedList = new SortedList<string, string>();
                string domainAndUsername = domain + @"\" + userLoginInfo.LoginName;
#pragma warning disable CA1416 // 验证平台兼容性
                DirectoryEntry de = new DirectoryEntry(ADPath, domainAndUsername, userLoginInfo.Password);

                src = new DirectorySearcher(de)
                {
                    Filter = "(SAMAccountName=" + userLoginInfo.UserName + ")",
                    //   此参数可以任意设置，但不能不设置，如不设置读取AD数据为0~999条数据，设置后可以读取大于1000条数据。 
                    PageSize = 1,
                    //   src.SizeLimit   =   2000; 
                    SearchScope = SearchScope.Subtree
                };

                try
                {
                    SearchResultCollection list = src.FindAll();
#pragma warning restore CA1416 // 验证平台兼容性
                    //LogHelpter.AddLog("获取用户信息成功");

                    string json = JsonConvert.SerializeObject(list);
                    userInfo = JsonConvert.DeserializeObject<UserInfo>(json.Replace("[{", "{").Replace("}]", "}"));
                    //LogHelpter.AddLog("获取用户信息:");
                    //LogHelpter.AddLog(json);
                    userInfo.IsSuccess = true;
                    userInfo.Token = JWTHelper.GetToken(JsonConvert.SerializeObject(userLoginInfo), JWTHelper.JWTSecret);
                }
                catch (Exception ex)
                {
                    userInfo.Path = ex.Message + Environment.NewLine + ex.StackTrace;
                    userInfo.IsSuccess = false;
                }
            }
            else
            {
                userInfo.Path = "User name or password error!";
                userInfo.IsSuccess = false;
            }
            return userInfo;
        }

        public bool ADUserValidate(string adAccount, string Password)
        {
#pragma warning disable CA1416 // 验证平台兼容性
            ImpersonationHelper helper = new ImpersonationHelper();
            bool result = false;
            if (helper.Impersonate("source-xm\\" + adAccount, Password))
            {
                //PrincipalContext adContext = new PrincipalContext(ContextType.Domain);
                //using (adContext)
                //{
                    //name = adContext.ConnectedServer;
//                    if (adContext.ValidateCredentials(adAccount, Password))
//#pragma warning restore CA1416 // 验证平台兼容性
//                    {
                        //验证成功
                        result = true;
                    //}
                    //else
                    //{
                    //    //验证失败
                    //    result = false;
                    //}
                //}
                helper.EndImpersonate();// 结束身份模拟。
            }
            else
            {
                // 如果模拟失败在这里处理。
            }
            return result;
        }
    }

    public class UserLoginInfo
    {
        public string UserName { get; set; }

        public string LoginName { get; set; }

        public string Password { get; set; }
    }

    public class UserInfo
    {
        public bool IsSuccess { get; set; }

        public string Path { get; set; }

        public string Token { get; set; }

        public Properties Properties { get; set; }
    }

    public class Properties
    {
        public List<int> badpwdcount { get; set; }
        public List<string> displayname { get; set; }
        public List<int> countrycode { get; set; }
        public List<int> lastlogoff { get; set; }
        public List<string> whenchanged { get; set; }
        public List<int> admincount { get; set; }
        public List<string> adspath { get; set; }
        public List<long> accountexpires { get; set; }
        public List<string> cn { get; set; }
        public List<int> codepage { get; set; }
        public List<string> distinguishedname { get; set; }
        public List<string> name { get; set; }
        public List<int> logoncount { get; set; }
        public List<long> samaccounttype { get; set; }
        public List<long> usncreated { get; set; }
        public List<string> objectcategory { get; set; }
        public List<string> dscorepropagationdata { get; set; }
        public List<long> badpasswordtime { get; set; }
        public List<string> userprincipalname { get; set; }
        public List<int> primarygroupid { get; set; }
        public List<string> whencreated { get; set; }
        public List<long> usnchanged { get; set; }
        public List<long> lastlogon { get; set; }
        public List<string> givenname { get; set; }
        public List<string> sn { get; set; }
        public List<string> objectguid { get; set; }
        public List<long> lastlogontimestamp { get; set; }
        public List<string> samaccountname { get; set; }
        public List<int> instancetype { get; set; }
        public List<string> objectsid { get; set; }
        public List<long> pwdlastset { get; set; }
        public List<string> memberof { get; set; }
        public List<string> objectclass { get; set; }
        public List<int> useraccountcontrol { get; set; }
    }
}
